package test;


import static org.junit.Assert.*;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import dsa.LinkedList;
import dsa.ListIterator;

public class GavinDavisTest {
	private LinkedList tester;
	private Object first;
	private Object second;
	private Object third;
	private Object fourth;

	@Before
	public void setUp()
	{
		tester = new LinkedList();
		first = new Object();
		second = new Object();
		third = new Object();
		fourth = new Object();

		first = "Bob";
		second = "Larry";
		third = "Amanda";
		fourth = "Claire";

		tester.addFirst(first);
		tester.addLast(second);
		tester.addLast(third);
		tester.addLast(fourth);
		
	}

	@After
	public void tearDown()
	{
		tester = null;
	}

	@Test
	public void testAddFirst()
	{
		
		assertEquals(tester.getFirst().equals("Claire"), false);
		Object o = "Bob";
		tester.addFirst(o);
		assertEquals(tester.getFirst().equals("Bob"), true);
	}
	
	@Test
	public void testIndexOf()
	{
		
		assertEquals(tester.indexOf("Larry") == 1, true);
		assertEquals(tester.size() == 4, true);
		Object o = "Bobby";
		tester.addLast(o);
		assertEquals(tester.size() == 5, true);
		assertEquals(tester.indexOf("Bobby") == 4, true);
		assertEquals(tester.remove(4).equals("Bobby"), true);
	}
	
	@Test
	public void testAddLast()
	{
		
		Object o = "Bobby";
		tester.addLast(o);
		tester.addLast(o);
		tester.addLast(o);
		assertEquals(tester.getLast().equals("Bobby"), true);
		Object o2 = "James";
		tester.addLast(o2);
		assertEquals(tester.getLast().equals("James"), true);
		assertEquals(tester.size() == 8, true);
		
	}

	@Test
	public void testSize() {
		
		Object o = null;
		tester.addFirst(o);
		assertEquals(tester.size() == 3,false);
		tearDown();
	}

	@Test
	public void testSize2()
	{
		
		tester.remove(3);
		assertEquals(tester.size() ==3, true);
		Object o = "Bob";
		tester.addFirst(o);
		tester.addFirst(o);
		tester.addFirst(o);
		tester.addFirst(o);
		tester.addFirst(o);
		tester.addFirst(o);
		tester.addFirst(o);
		tester.addFirst(o);
		tester.addFirst(o);
		assertEquals(tester.size()*12 == 144, true);
		
		
	}

	@Test
	public void testGetFirst()
	{
		
		assertEquals(tester.getFirst().equals(tester.get(0)), true);
		tester.remove(0);
		assertEquals(tester.getFirst().equals("Larry"), true);
		tester.removeFirst();
		assertEquals(tester.getFirst().equals("Amanda"), true);
		tester.removeFirst();
		assertEquals(tester.getFirst().equals("Claire"), true);
		
	}

	@Test
	public void testClone()
	{
		
		LinkedList temp = (LinkedList) tester.clone();

		assertEquals((temp.getFirst().equals("Bob")), true);
		assertEquals((temp.get(1).equals("Larry")), true);
		assertEquals((temp.get(2).equals("Amanda")), true);
		assertEquals((temp.getLast().equals("Claire")), true);
	}

	@Test
	public void testContains() {
		
		Object o = "Bob2";
		assertEquals(tester.get(0).equals("Bob"), true);
		tester.addFirst(o);
		tester.removeFirst();
		tester.addFirst(o);
		assertEquals(tester.contains("Bob2"),true);
	}
	
	/**
	 * LISTITERATOR TESTS
	 * 
	 * Bob
	 * Larry
	 * Amanda
	 * Claire
	 */
	
	@Test
	public void testNext()
	{
		ListIterator it = tester.listIterator(0);
		assertTrue(it.hasNext());
		assertEquals(it.nextIndex() == 0, true);
		assertEquals(it.next().equals("Bob"), true);
		assertTrue(it.hasNext());
		assertEquals(it.nextIndex() == 1, true);
		assertEquals(it.next().equals("Larry"), true);
		assertTrue(it.hasNext());
		assertEquals(it.nextIndex() == 2, true);
		assertEquals(it.next().equals("Amanda"), true);
		assertTrue(it.hasNext());
		assertEquals(it.nextIndex() == 3, true);
		assertEquals(it.next().equals("Claire"), true);
		assertFalse(it.hasNext());
		assertEquals(it.nextIndex() == tester.size(), true);
		
	}
	
	@Test
	public void testPrevious()
	{
		ListIterator it = tester.listIterator(4);
		assertFalse(it.hasNext());
		assertEquals(it.nextIndex() == tester.size(), true);
		assertTrue(it.hasPrevious());
		assertEquals(it.previousIndex() == 3, true);
		assertEquals(it.previous().equals("Claire"), true);
		assertTrue(it.hasPrevious());
		assertEquals(it.previousIndex() == 2, true);
		assertEquals(it.previous().equals("Amanda"), true);
		assertTrue(it.hasPrevious());
		assertEquals(it.previousIndex() == 1, true);
		assertEquals(it.previous().equals("Larry"), true);
		assertTrue(it.hasPrevious());
		assertEquals(it.previousIndex() == 0, true);
		assertEquals(it.previous().equals("Bob"), true);
		assertFalse(it.hasPrevious());
		assertEquals(it.previousIndex() == -1, true);
	}
	
	@Test
	public void testRemoveAndAdd()
	{
		ListIterator it = tester.listIterator(0);
		it.next();
		assertEquals(tester.size() == 4, true);
		it.remove();
		assertEquals(tester.size() == 3, true);
		it.next();
		assertEquals(tester.size() == 2, true);
		assertTrue(it.next().equals("Amanda"));
		it.remove();
		assertEquals(tester.size() == 1, true);
		assertTrue(it.next().equals("Claire"));
		it.add("Bobby");
		assertEquals(tester.size() == 1, true);
		assertTrue(it.next().equals("Bobby"));
		it.add("Kyle");
		assertTrue(tester.getLast().equals("Kyle"));
		
		
	}
	
	@Test
	public void testSet()
	{
		ListIterator it = tester.listIterator(0);
		assertTrue(it.next().equals("Bob"));
		it.set("David");
		assertTrue(tester.get(0).equals("David"));
		assertTrue(it.next().equals("Larry"));
		it.set("Kyle");
		assertTrue(tester.get(1).equals("Kyle"));
		assertTrue(it.previous().equals("David"));
		it.set("Charlie");
		assertTrue(tester.get(0).equals("Charlie"));
		
	}

}
